import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

/*
 * Created on Oct 9, 2006
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author metrock
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class IndexReader {
	public static final String DELIMITER = "==";
	public static final String ENDING_DELIMITER = "##";
	
	public static void readInIndex(String filename, Vector words) throws IOException, FileNotFoundException{
		String todays_date_and_time, break_chars, stop_word_file,
	           total_corpus_char_size, total_corpus_word_size, 
		       total_corpus_line_size, total_number_corpus_files;
			
			FileInputStream stream = new FileInputStream(filename);			
			
			// Start of static header gathering
			todays_date_and_time = (String) readInWord(stream)[0];
			break_chars = (String) readInWord(stream)[0];
			stop_word_file = (String) readInWord(stream)[0];
			if(stop_word_file.equals(""))
				stop_word_file = "None";
			total_corpus_char_size = (String) readInWord(stream)[0];
			total_corpus_word_size = (String) readInWord(stream)[0];
			total_corpus_line_size = (String) readInWord(stream)[0];
			total_number_corpus_files = (String) readInWord(stream)[0];
			
			Vector names_of_files = new Vector();
			Vector character_size = new Vector();
			Vector word_size = new Vector();
			Vector line_size = new Vector();
			Vector size_of_complete_file_bloom = new Vector();
			Vector size_of_line_bloom = new Vector();
			
			while (true) { // All right! An infinite loop.
				names_of_files.add(readInWord(stream)[0]);
				character_size.add(readInWord(stream)[0]);
				word_size.add(readInWord(stream)[0]);
				line_size.add(readInWord(stream)[0]);
				size_of_complete_file_bloom.add(readInWord(stream)[0]);
				// Are we done?
				Object[] result = readInWord(stream);
				size_of_line_bloom.add(result[0]);
				if (((Boolean) result[1]).booleanValue() == true) {
					break;  // Aha!  A way out.
				}				
			}
			
			if(words == null){
			
			//System.out.println("Contents of Index File: " + filename);
			System.out.println("Date of Creation: " + todays_date_and_time);
			System.out.println("Variable Break Characters: " + break_chars);
			System.out.println("Stop-word file: " + stop_word_file);
			
			System.out.println("");
			
			for (int i = 0 ; i < names_of_files.size(); i++) {
				System.out.println("File Name: " + names_of_files.get(i));
				//System.out.println("\tSize (chars): " + character_size.get(i));
				System.out.println("Size (words): " + word_size.get(i));
				System.out.println("Size (lines): " + line_size.get(i));
				//System.out.println("Complete Bloom Filter Size: " + size_of_complete_file_bloom.get(i));
				//System.out.println("Bloom Filter Size for a line: " + size_of_line_bloom.get(i));								
			}
			
			System.out.println("");
			
			System.out.println("Corpus Size (chars): " + total_corpus_char_size);
			System.out.println("Corpus Size (words): " + total_corpus_word_size);
			System.out.println("Corpus Size (lines): " + total_corpus_line_size);
			System.out.println("Files in the corpus: " + total_number_corpus_files);
			// End of static header gathering
			
			
			} else {
				// We're not done, drat.
				// For every file, we need to get the bloom filters for it.
				
				// Represents everything you need from a file.
				// Each entry is a vector where [0] filename, [1] bloom filter for file, 
				// [2] array of bloom filters for lines
				Vector fileInfo = new Vector();
				for (int i = 0 ; i < names_of_files.size(); i++) {
					Vector a_file = new Vector();
					a_file.add(names_of_files.get(i));
					BloomFilter complete_file_bloom = new BloomFilter(stream, Integer.parseInt((String) size_of_complete_file_bloom.get(i)));
					a_file.add(complete_file_bloom);
					
					BloomFilter[] line_bloom_filters = new BloomFilter[Integer.parseInt((String)line_size.get(i))];
					for (int p = 0; p < line_bloom_filters.length; p++) {
						line_bloom_filters[p] = new BloomFilter(stream, Integer.parseInt((String) size_of_line_bloom.get(i)));
						
					}
					a_file.add(line_bloom_filters);
					fileInfo.add(a_file);
				}
				
				// For each word, cycle through.
				for (Iterator i = words.iterator(); i.hasNext();) {
					String word = (String) i.next();
					word = word.toLowerCase();
					System.out.println("Word: \"" + word + "\"");
					for (Iterator j = fileInfo.iterator(); j.hasNext();) {
						Vector a_file = (Vector) j.next();
						String name = (String) a_file.get(0);
						BloomFilter complete_file_bloom = (BloomFilter) a_file.get(1);
						BloomFilter[] line_bloom_filters = (BloomFilter[]) a_file.get(2);
						if (complete_file_bloom.wordExists(word)) {
							// Word exists, traverse all line bloom filters
							System.out.println("File Path: \"" + name + "\"");
							for (int p = 0 ; p < line_bloom_filters.length; p++) {
								if (line_bloom_filters[p].wordExists(word)) {
									System.out.println("Line: " + (p + 1));
									for (int q = 2;;q++) {
										if (line_bloom_filters[p].wordExists(word + "+" + q)) {
											System.out.println("Line: " + (p + 1));
										} else {
											break;
										}
									}
								}
								
							}	
							System.out.println("");
						}
					}
					
				}
			}
	}
	
	public static Object[] readInWord(FileInputStream stream) throws IOException {
		byte[] buf = new byte[1];
		String word = "";
		boolean haveSeenDelimiterBefore = false;
		boolean haveSeenEndingDelimiterBefore = false;
		
		while (stream.read(buf) == 1) {
			char c = (char) buf[0];
			if (c == DELIMITER.charAt(0)) {
				if (haveSeenDelimiterBefore) {
					return new Object[]{word,new Boolean(false)};
				} else {
					haveSeenDelimiterBefore = true;
				}
			} else if (c == ENDING_DELIMITER.charAt(0)) {
				if (haveSeenEndingDelimiterBefore) {
					return new Object[]{word,new Boolean(true)};
				} else {
					haveSeenEndingDelimiterBefore = true;
				}
			} else {
				if (haveSeenDelimiterBefore) {
					word += DELIMITER.charAt(0);					
				}
				if (haveSeenEndingDelimiterBefore) {
					word += ENDING_DELIMITER.charAt(0);
				}
				haveSeenDelimiterBefore = false;
				haveSeenEndingDelimiterBefore = false;
				word += c;
			}
		}
		
		return null;
	}
}
